package com.huawei.demo;

import com.huaweicloud.sdk.core.auth.BasicCredentials;
import com.huaweicloud.sdk.core.auth.ICredential;
import com.huaweicloud.sdk.core.exception.ConnectionException;
import com.huaweicloud.sdk.core.exception.RequestTimeoutException;
import com.huaweicloud.sdk.core.exception.ServiceResponseException;
import com.huaweicloud.sdk.core.region.Region;
import com.huaweicloud.sdk.gaussdbfornosql.v3.GaussDBforNoSQLClient;
import com.huaweicloud.sdk.gaussdbfornosql.v3.model.ListInstancesRequest;
import com.huaweicloud.sdk.gaussdbfornosql.v3.model.ListInstancesResponse;
import com.huaweicloud.sdk.gaussdbfornosql.v3.model.ResizeInstanceVolumeRequest;
import com.huaweicloud.sdk.gaussdbfornosql.v3.model.ResizeInstanceVolumeRequestBody;
import com.huaweicloud.sdk.gaussdbfornosql.v3.model.ResizeInstanceVolumeResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ReplicaSetEnlargeVolumeDemo {

    private static final Logger logger = LoggerFactory.getLogger(ReplicaSetEnlargeVolumeDemo.class.getName());

    private static final String RESIZE_VOLUME_ACTION = "RESIZE_VOLUME";

    /**
     * args[0] = "<YOUR IAM_END_POINT>"
     * args[1] = "<YOUR END_POINT>"
     * args[2] = "<YOUR AK>"
     * args[3] = "<YOUR SK>"
     * args[4] = "<YOUR INSTANCE_ID>"
     * args[5] = "<YOUR REGION_ID>"
     *
     * @param args
     */
    public static void main(String[] args) throws InterruptedException {
        if (args.length != 6) {
            logger.info("Illegal Arguments");
        }

        String iamEndpoint = args[0];
        String endpoint = args[1];

        String ak = args[2];
        String sk = args[3];

        String instanceId = args[4];
        String regionId = args[5];

        ICredential auth = new BasicCredentials()
                .withIamEndpoint(iamEndpoint)
                .withAk(ak)
                .withSk(sk);

        GaussDBforNoSQLClient client = GaussDBforNoSQLClient.newBuilder()
                .withCredential(auth)
                .withRegion(new Region(regionId, endpoint))
                .build();

        // 查看副本集实例存储空间
        // 通过实例ID调用ListInstances接口获取实例详情信息
        ListInstancesResponse currentResponse = showGaussDBforNoSQLReplicaSetDetail(client, instanceId);

        // currentSize: 在实例详情中获取实例当前存储空间
        String currentSize = currentResponse.getInstances().get(0).getGroups().get(0).getVolume().getSize();
        logger.info("Replicaset storage space is {}", currentSize);

        // 扩容副本集存储空间
        // targetSize:待扩容到的磁盘容量。取值为10的整数倍，并且大于当前磁盘容量,这里当前容量(currentSize)大小加上10为例
        int targetSize = Integer.valueOf(currentSize) + 10;
        enlargeGaussDBforNoSQLReplicaSetVolume(client, instanceId, targetSize);

        // 等待扩容完成,示例中为了避免过多发出请求，设置了1min睡眠。
        while (!completeEnlargeVolume(client, instanceId)) {
            Thread.sleep(60000L);
        }

        // 等待扩容成功后再通过调用实例ID详情接口查询扩容后实例存储空间
        ListInstancesResponse targetResponse = showGaussDBforNoSQLReplicaSetDetail(client, instanceId);
        String expansionSize = targetResponse.getInstances().get(0).getGroups().get(0).getVolume().getSize();
        logger.info("The  Replicaset storage space after enlarge volume is {}", expansionSize);
    }

    private static ListInstancesResponse showGaussDBforNoSQLReplicaSetDetail(GaussDBforNoSQLClient client, String instanceId) {
        ListInstancesRequest request = new ListInstancesRequest();
        request.withId(instanceId);
        ListInstancesResponse response = new ListInstancesResponse();
        try {
            response = client.listInstances(request);
            logger.info("show instance detail response:{}", response.toString());
        } catch (ConnectionException e) {
            logger.error("ConnectionException", e);
        } catch (RequestTimeoutException e) {
            logger.error("RequestTimeoutException ", e);
        } catch (ServiceResponseException e) {
            logger.error("httpStatusCode: {}, errorCode: {}, errorMsg: {}", e.getHttpStatusCode(), e.getErrorCode(), e.getErrorMsg());
        }
        return response;
    }

    private static boolean completeEnlargeVolume(GaussDBforNoSQLClient client, String instanceId) {
        // 通过查询实例详情与列表接口的actions字段中不包含RESIZE_VOLUME action
        ListInstancesRequest request = new ListInstancesRequest();
        request.withId(instanceId);
        try {
            ListInstancesResponse rsp = client.listInstances(request);
            if (!rsp.getInstances().get(0).getActions().contains(RESIZE_VOLUME_ACTION)) {
                return true;
            }
        } catch (ConnectionException e) {
            logger.error("ConnectionException", e);
        } catch (RequestTimeoutException e) {
            logger.error("RequestTimeoutException ", e);
        } catch (ServiceResponseException e) {
            logger.error("httpStatusCode: {}, errorCode: {}, errorMsg: {}", e.getHttpStatusCode(), e.getErrorCode(), e.getErrorMsg());
        }
        return false;
    }

    private static String enlargeGaussDBforNoSQLReplicaSetVolume(GaussDBforNoSQLClient client, String instanceId, int targetSize) {
        ResizeInstanceVolumeRequest request = new ResizeInstanceVolumeRequest();
        ResizeInstanceVolumeRequestBody body = new ResizeInstanceVolumeRequestBody();
        body.setSize(targetSize);
        request.withBody(body);
        request.setInstanceId(instanceId);
        ResizeInstanceVolumeResponse response = new ResizeInstanceVolumeResponse();
        try {
            response = client.resizeInstanceVolume(request);
            logger.info("enlarge volume size rsp:{}", response.toString());
        } catch (ConnectionException e) {
            logger.error("ConnectionException", e);
        } catch (RequestTimeoutException e) {
            logger.error("RequestTimeoutException ", e);
        } catch (ServiceResponseException e) {
            logger.error("httpStatusCode: {}, errorCode: {}, errorMsg: {}", e.getHttpStatusCode(), e.getErrorCode(), e.getErrorMsg());
        }
        return response.getJobId();
    }
}
